<template>
  <div>
    <!-- 地图 -->
    <div id="container"></div>
  </div>
</template>
<script>
import { bus } from '@/main.js';
import AMapLoader from '@amap/amap-jsapi-loader';
import { mapState, mapMutations } from 'vuex';

export default {
  name: 'MapContainer',
  mixins: [], //混入
  components: {}, //组件
  props: {}, //集成属性
  data() {
    return {
      center: {},
      map: null,
      marker: null,
      positionInfo: {
        lng: 119.30692,
        lat: 26.078093,
        address: '1111',
        province: '',
        city: '',
        district: '',
        street: '',
        streetNumber: '',
        zipcode: '',
        country: '',
        township: '',
      },
    };
  },
  computed: {
    ...mapState(['MAP']),
    bounds: function() {
      let _ = this._;
      if (!this.map) return null;
      let bounds = this.map.getBounds();
      return {
        c: bounds.getCenter(),
        sw: bounds.getSouthWest(),
        ne: bounds.getNorthEast(),
      };
    }, //返回视窗中心点、西南角、东北角，可作为请求时的参数
  },
  methods: {
    initAMap() {
      window._AMapSecurityConfig = {
        securityJsCode: this.MAP.securityJsCode, //「你申请的安全密钥」
      };
      return AMapLoader.load({
        key: this.MAP.key, // 申请好的Web端开发者Key，首次调用 load 时必填
        version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
        plugins: [
          'AMap.ToolBar',
          'AMap.Scale',
          'AMap.Geocoder',
          'AMap.Geolocation',
          'AMap.PlaceSearch',
          'AMap.AutoComplete',
          'AMap.ElasticMarker',
          'AMap.CitySearch',
        ], // 需要使用的的插件列表，如比例尺'AMap.Scale'，支持添加多个如：['...','...']
        resizeEnable: true,
      })
        .then((AMap) => {
          this.map = new AMap.Map('container', {
            // 设置地图容器id
            viewMode: '3D', // 是否为3D地图模式
            zoom: 11, // 初始化地图级别
            center: [this.positionInfo.lng, this.positionInfo.lat], // 初始化地图中心点位置
            scrollWheel: true, // 是否开启鼠标滚轮缩放
            // mapStyle: 'amap://styles/normal',
            // mapStyle: 'amap://styles/darkblue', // 极夜蓝（darkblue）
            // mapStyle: 'amap://styles/graffiti', // 涂鸦（graffiti）
          });

          this.getCurrentLocation(); // 获取当前定位

          this.geocoder = new AMap.Geocoder();

          this.map.addControl(new AMap.Scale()); // 在图面添加比例尺控件，展示地图在当前层级和纬度下的比例尺
          this.map.addControl(new AMap.ToolBar()); // 在图面添加鹰眼控件，在地图右下角显示地图的缩略图

          return this.map;
        })

        .catch((e) => {
          console.log(e);
        });
    },
    //获取当前定位
    getCurrentLocation() {
      let that = this;
      that.geolocation = new AMap.Geolocation({
        timeout: 5000, // 超过3秒后停止定位，默认：5s
        enableHighAccuracy: true, // 进行浏览器原生定位的时候是否尝试获取较高精度
        zoomToAccuracy: true, // 定位成功后是否自动调整级别
      });

      // 获取用户的精确位置，有失败几率,需要一个兜底措施
      that.geolocation.getCurrentPosition(function(status, result) {
        // 备注：getCurrentPosition方法会调用超时或失败：
        // Get geolocation time out：浏览器定位超时，包括原生的超时，可以适当增加超时属性的设定值以减少这一现象。
        // 另外还有个别浏览器（如google Chrome浏览器等）本身的定位接口是黑洞，通过其请求定位完全没有回应，也会超时返回失败。
        // Get geolocation failed：定位失败，Chrome、火狐以及部分套壳浏览器接入的定位服务在国外，有较大限制，失败率高。
        if (status == 'complete') {
          that.onComplete(result);
        } else {
          that.onError(result); //失败后可使用getCityInfo获取非精准定位（具体到省市）
        }
      });
    },

    //解析定位结果
    onComplete(data) {
      let lnglat = data.position;
      this.positionInfo.lng = lnglat[0];
      this.positionInfo.lat = lnglat[1];
      let marker = new AMap.Marker({
        //创建标记
        position: new AMap.LngLat(lnglat[0], lnglat[1]),
      });
      this.map.clearMap(); // 清除所有覆盖物（点标志）
      this.map.add(marker); // 添加点标志
      let that = this;
      // 经纬度转换为中文地址详情
      that.geocoder.getAddress(lnglat, function(status, result) {
        if (status === 'complete' && result.regeocode) {
          this.positionInfo.address = result.regeocode.formattedAddress;
        } else {
          that.$message.error('根据经纬度查询地址失败');
        }
      });
    },

    //解析定位错误信息
    onError(data) {
      this.getLngLatLocation();
    },

    //在获取具体定位失败时调用的代码：（非精准定位！！！）
    getLngLatLocation() {
      const that = this;
      that.geolocation.getCityInfo((status, result) => {
        if (status === 'complete') {
          let data = result.position;
          that.positionInfo.lng = data[0];
          that.positionInfo.lat = data[1];
          that.positionInfo.address = result.province + result.city;
        } else {
          that.$message.error('获取地址失败');
        }
      });
    },
  },
  beforeCreate: function() {},
  created: function() {},
  beforeMount: function() {},
  mounted: function() {
    this.initAMap();
  },
  beforeUpdate: function() {},
  updated: function() {},
  beforeDestroy: function() {
    if (this.map) {
      this.map.destroy();
    }
  },
  destroyed: function() {},
};
</script>
<style scoped lang="less"></style>
